using Engine;
using Game;

namespace SCIENEW.VoltNet {
    public class VoltConnection {
        public Dictionary<CellFace, VoltElement> m_containsElements;

        public VoltConnection(Dictionary<CellFace, VoltElement> containsElements) {
            m_containsElements = containsElements;
        }

        public Vector3 CalcCenterPos() {
            Vector3 v = Vector3.Zero;
            foreach (var element in m_containsElements) {
                Vector3 pos = new Vector3(element.Key.Point) + new Vector3(0.5f) + CellFace.FaceToVector3(element.Key.Face) * 0.4f;
                v += pos;
            }
            v /= m_containsElements.Count;
            return v;
        }

        public void Simulate(float dt) {
            float totalInputPower = 0f;
            float inputVoltage = 0f;
            int generatorCount = 0;

            // 计算发电机的总功率并检查电压一致性
            foreach (var element in m_containsElements) {

                int blockValue = element.Value.BlockValue;

                if (IsGenerator(element.Value, element.Key)) {
                    float generatorVoltage = GetElementUL(blockValue, element.Value, element.Key);//获取电压
                    if (generatorCount == 0) {
                        inputVoltage = generatorVoltage;
                    } else if (generatorVoltage != inputVoltage) {
                        // 电压不一致，可能导致问题，进行处理
                        HandleVoltageMismatch();
                        return;
                    }
                    totalInputPower += GetElementPL(blockValue, element.Value, element.Key);
                    generatorCount++;
                }
            }

            // 如果没有发电机，则没有输入功率
            if (generatorCount == 0) {
                inputVoltage = 0;
            }

            // 计算每个用电器的功率需求
            float totalRequiredPower = 0f;
            foreach (var element in m_containsElements) {

                int blockValue = element.Value.BlockValue;

                if (IsConsumer(element.Value, element.Key)) {
                    totalRequiredPower += Math.Abs(GetElementPL(blockValue, element.Value, element.Key));
                }
            }

            // 分配功率并更新每个用电器的状态
            foreach (var element in m_containsElements) {
                if (IsConsumer(element.Value, element.Key)) {

                    int blockValue = element.Value.BlockValue;

                    float allocatedPower = (totalRequiredPower > 0) ? totalInputPower * (Math.Abs(GetElementPL(blockValue, element.Value, element.Key)) / totalRequiredPower) : 0;
                    element.Value.UpdateWorkState(allocatedPower, inputVoltage, Math.Abs(GetElementPL(blockValue, element.Value, element.Key)), Math.Abs(GetElementUL(blockValue, element.Value, element.Key)));
                }
            }
        }

        private bool IsGenerator(VoltElement element, CellFace cellFace) {
            // 判定元件是否为发电机
            int blockValue = element.BlockValue;
            DeviceBlock deviceBlock = DevicesBlockManager.GetDevice(blockValue);
            IVoltDevice voltDevice = deviceBlock as IVoltDevice;
            return element.GetPL(voltDevice.GetStandardPL(blockValue, cellFace), cellFace) > 0;
        }

        private bool IsConsumer(VoltElement element, CellFace cellFace) {
            // 判定元件是否为用电器
            int blockValue = element.BlockValue;
            DeviceBlock deviceBlock = DevicesBlockManager.GetDevice(blockValue);
            IVoltDevice voltDevice = deviceBlock as IVoltDevice;
            return element.GetPL(voltDevice.GetStandardPL(blockValue, cellFace), cellFace) < 0;
        }

        private void HandleVoltageMismatch() {
            // 处理发电机电压不一致的情况
            // 可以抛出错误或者采取其他措施
            throw new InvalidOperationException("发电机电压不一致！");
        }

        /// <summary>
        /// 获取元件的额定功率
        /// </summary>
        /// <returns></returns>
        public float GetElementPL(int blockValue, VoltElement voltElement, CellFace cellFace) {
            DeviceBlock deviceBlock = DevicesBlockManager.GetDevice(blockValue);
            IVoltDevice voltDevice = deviceBlock as IVoltDevice;

            return voltElement.GetPL(voltDevice.GetStandardPL(blockValue, cellFace), cellFace);
        }

        /// <summary>
        /// 获取元件的额定电压
        /// </summary>
        /// <param name="blockValue"></param>
        /// <param name="voltElement"></param>
        /// <param name="cellFace"></param>
        /// <returns></returns>
        public float GetElementUL(int blockValue, VoltElement voltElement, CellFace cellFace) {
            DeviceBlock deviceBlock = DevicesBlockManager.GetDevice(blockValue);
            IVoltDevice voltDevice = deviceBlock as IVoltDevice;

            return voltElement.GetUL(voltDevice.GetStandardUL(blockValue, cellFace), cellFace);
        }
    }
}